package com.tianji.learning.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.constants.CacheConstant;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.po.PointsBoard;
import com.tianji.learning.domain.query.PointsBoardQuery;
import com.tianji.learning.domain.vo.PointsBoardItemVO;
import com.tianji.learning.domain.vo.PointsBoardVO;
import com.tianji.learning.mapper.PointsBoardMapper;
import com.tianji.learning.service.IPointsBoardService;
import com.tianji.learning.service.UserQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.tianji.common.constants.Constant.POINTS_BOARD_PREFIX;

/**
 * <p>
 * 学霸天梯榜 服务实现类
 * </p>
 *
 * @author xjs
 */
@Slf4j
@Service
public class PointsBoardServiceImpl extends ServiceImpl<PointsBoardMapper, PointsBoard> implements IPointsBoardService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserClient userClient;
    @Autowired
    private UserQueryService userQueryService;


    @Override
    public PointsBoardVO getBoard(PointsBoardQuery pageQuery) {
        PointsBoardVO vo= new PointsBoardVO();
        // 当前用户
        Long userId = UserContext.getUser();
        // 榜单的key
        String yyyyMM = LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMM");
        String key = CacheConstant.POINTS_BOARD+yyyyMM;
        // 先判断是当前赛季还是历史赛季
        Long season = pageQuery.getSeason();
        if(season == null || season <=0 ){
            // 当前赛季
            // 我的积分
            Double score = redisTemplate.opsForZSet().score(key, "" + userId);
            vo.setPoints(score==null?0:score.intValue());
            // 我的排名
            Long rank = redisTemplate.opsForZSet().reverseRank(key, "" + userId);
            vo.setRank(rank == null?-1:rank.intValue()+1);
            // 分页查询zset排行榜
            // 起始索引,每页10，  1页0，2页10，3页20
            int start = (pageQuery.getPageNo()-1)*pageQuery.getPageSize();
            // 结束索引，每页10，  1页10-1，2页20-1，3页30-1
            int end = pageQuery.getPageNo() * pageQuery.getPageSize() - 1;
            Set<ZSetOperations.TypedTuple<String>> typedTuples = redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
            if(CollUtils.isEmpty(typedTuples)){

            }else{
                List<PointsBoardItemVO> boardList = new ArrayList<>();
                ArrayList<ZSetOperations.TypedTuple<String>> tupleList = new ArrayList<>(typedTuples);
                for (int i =0; i<tupleList.size(); i++) {
                    ZSetOperations.TypedTuple<String> typedTuple = tupleList.get(i);
                    Double userScore = typedTuple.getScore();
                    String userIdstring = typedTuple.getValue();
                    PointsBoardItemVO itemVO = new PointsBoardItemVO();
                    itemVO.setUserId(Long.parseLong(userIdstring));
                    itemVO.setName(userIdstring);
                    itemVO.setRank(start + i + 1);//根据索引，计算排名
                    itemVO.setPoints(userScore.intValue());
                    boardList.add(itemVO);
                }
                // userId 转 userName
                Map<Long, UserDTO> userMap = userQueryService.queryUserMap(boardList);
                for (PointsBoardItemVO itemVO : boardList) {
                    UserDTO userDTO = userMap.get(Long.parseLong(itemVO.getName()));
                    itemVO.setName(userDTO==null?"":userDTO.getName());
                }
                vo.setBoardList(boardList);
            }
        }else{
            // 历史赛季
            // 查询我的积分和排名
            Long seasonId = pageQuery.getSeason();
            String tableName = POINTS_BOARD_PREFIX + seasonId;
            PointsBoardItemVO itemVO =  this.baseMapper.queryByUserId(tableName, userId);
            if(itemVO != null){
                vo.setRank(itemVO.getRank());
                vo.setPoints(itemVO.getPoints());
            }
            // 分页查询当前页列表
            int start = (pageQuery.getPageNo()-1)*pageQuery.getPageSize();
            List<PointsBoardItemVO> itemVos = this.baseMapper.selectPageData(tableName,start, pageQuery.getPageSize());
            if(!CollUtils.isEmpty(itemVos)){
                // userId - > userName
                Map<Long, UserDTO> userMap = userQueryService.queryUserMap(itemVos);
                for (PointsBoardItemVO item : itemVos) {
                    UserDTO userDTO = userMap.get(item.getUserId());
                    item.setName(userDTO==null?"":userDTO.getName());
                }
            }
            vo.setBoardList(itemVos);
        }
        return vo;
    }
}
